package rps.client;

import java.awt.Dimension;

import javax.swing.JFrame;

import rps.client.ui.BoardPanel;
import rps.client.ui.GamePane;
import rps.client.ui.MediaProvider;
import rps.client.ui.Menu;
import rps.client.ui.StartupPane;
import rps.client.ui.WaitingPane;
import rps.game.Game;
import rps.game.data.AttackResult;
import rps.game.data.Figure;
import rps.game.data.FigureKind;
import rps.game.data.Player;


public class UIController implements GCtoUIInterface {

	private StartupPane startupPane;
	private WaitingPane waitingPane;
	private GamePane gamePane;
	public GameController gameController;
	private Menu menu;
	private JFrame frame;
	
	private Player player, opponent;
	
	public static final int
			CONTROLWIDTH = 300,
			BOARDPANEHEIGHT = BoardPanel.ROWS*100,
			BOARDPANEWIDTH = BoardPanel.COLS*100,
			FLAGNOTSET = 0,
			TRAPNOTSET = 1,
			ALLSET = 2,
			GAME = -1;
	public static final Dimension
			BOARD_DIMENSION = new Dimension(BOARDPANEWIDTH, BOARDPANEHEIGHT),
			CONTROL_DIMENSION = new Dimension(CONTROLWIDTH, BOARDPANEHEIGHT),
			//Boardpaneheight + 50 for statusbar
			GAME_DIMENSION = new Dimension(BOARDPANEWIDTH+CONTROLWIDTH, BOARDPANEHEIGHT+50),
			STARTUP_DIMENSION = new Dimension(400, 460),
			WAITING_DIMENSION = new Dimension(400, 460);
	
	public int placementPhase;
	
	public void setComponents(JFrame frame, Menu menu, StartupPane startupPane, WaitingPane waitingPane, GamePane gamePane,
			GameController gameController) {
		this.frame = frame;
		this.menu = menu;
		this.startupPane = startupPane;
		this.waitingPane = waitingPane;
		this.gamePane = gamePane;
		this.gameController = gameController;
		
		MediaProvider.getMediaProvider().playMusic(true);
		
		
	}
	public int getPlacementPhase() {
		return placementPhase;
	}
	public void setPlacementPhase(int placementPhase) {
		this.placementPhase = placementPhase;
	}
	public void setPlayer(Player player){
		this.player = player;
	}
	public Player getPlayer(){
		return player;
	}

	public void handleSurrender() {
		gameController.surrender();
		menu.gameEnded();
	}

	public void handleExit() {
		gameController.exit();
		System.exit(0);
	}

	public void handleNewGame() {
		gameController.surrender();
		
		player = null;
		opponent = null;
		
		gameController.resetForNewGame();
		menu.reset();
		startupPane.reset();
		waitingPane.reset();
		gamePane.reset();
		
		setPlacementPhase(UIController.FLAGNOTSET);
		
		startupPane.show();
		frame.setSize(STARTUP_DIMENSION);
		frame.setLocationRelativeTo(null);
		waitingPane.hide();
		gamePane.hide();
	}

	public void switchToWaitingForOpponentPane() {
		startupPane.hide();
		waitingPane.show();
		frame.setSize(WAITING_DIMENSION);
		frame.setLocationRelativeTo(null);
	}

	public void stopWaitingAndSwitchBackToStartup() {
		gameController.unregister();
		switchBackToStartup();
	}

	@Override
	public void switchToGamePane() {
		menu.gameStarted();
		waitingPane.hide();		
		frame.pack();
		frame.setLocationRelativeTo(null);
	}

	public void switchBackToStartup() {
		waitingPane.hide();
		startupPane.show();
		frame.setSize(STARTUP_DIMENSION);
		frame.setLocationRelativeTo(null);
	}
	
	@Override
	public void receivedMessage(Player sender, String message){
		gamePane.receivedMessage(sender, message);
	}
	
	@Override
	public void startGame(Game game, Player opponent) {
		gamePane.startGame(game);
		this.opponent = opponent;
	}

	@Override
	public void updateBoard(Figure[] field) {
		gamePane.updateBoard(field);
	}
	
	@Override
	public void initialChoiceDraw() {
		gamePane.enableWeaponChoicePanel(true);
		gamePane.setStatusText("Unentschieden. Wählen Sie eine neue Figur.");		
	}

	@Override
	public void gameStarted() {
		gamePane.setPlacementPhaseWithEnabling(UIController.GAME);
		menu.gameStarted();
		gamePane.repaintBoard();
	}

	@Override
	public void provideNextMove() {
		gamePane.enableButtons(true);
		gamePane.setStatusText("Sie sind dran!");		
	}
	
	@Override
	public void figureMoved(int fromIndex, int toIndex, Figure[] newField){
		gamePane.figureMoved(fromIndex, toIndex, newField);
	}
	
	@Override
	public void figureAttacked(int fromIndex, int toIndex, Figure attackingFigure, Figure defendingFigure, Figure[] newField){
		String privatemessage = "";
		if(attackingFigure.belongsTo(player)){
			privatemessage = player.getNick() + " hat mit " + figureToString(attackingFigure) + " " + opponent.getNick() + "'s " + figureToString(defendingFigure) + " angegriffen";
		}
		else{			
			privatemessage = opponent.getNick() + " hat mit " + figureToString(attackingFigure) + " " + player.getNick() + "'s " + figureToString(defendingFigure) + " angegriffen";
		}
		
		if(attackingFigure.attack(defendingFigure).equals(AttackResult.WIN)) privatemessage += " und gewonnen.";
		else privatemessage += " und verloren.";
		
		gamePane.receivedMessage(null, privatemessage);
		gamePane.figureAttacked(fromIndex, toIndex, attackingFigure, defendingFigure, newField);
	}
	
	private String figureToString(Figure f){
		if(f.equals(null)) throw new RuntimeException("Figure can't be null. Must have attacked empty field.");
		else if(f.getKind().equals(FigureKind.ROCK)) return "Stein";
		else if(f.getKind().equals(FigureKind.PAPER)) return "Papier";
		else if(f.getKind().equals(FigureKind.SCISSORS)) return "Schere";
		else if(f.getKind().equals(FigureKind.TRAP)) return "Falle";
		else if(f.getKind().equals(FigureKind.FLAG)) return "Flagge";
		else return f.getKind().toString();
	}
	
	@Override
	public void provideChoiceAfterFightIsDrawn(){
		gamePane.enableWeaponChoicePanel(true);
		gamePane.setStatusText("Der Kampf endete unentschieden. Wählen Sie eine neue Figur!");
	}

	@Override
	public void gameIsLost() {
		menu.gameEnded();
		gamePane.setStatusText("Verloren");
		gamePane.enableButtons(false);
		gamePane.receivedMessage(null, "Schande! Du hast verloren.");
		
	}

	@Override
	public void gameIsWon() {
		menu.gameEnded();
		gamePane.setStatusText("Gewonnen");
		gamePane.enableButtons(false);
		gamePane.receivedMessage(null, "Herzlichen Glückwunsch! Du hast gewonnen.");
		
	}

	@Override
	public void gameIsDrawn() {
		menu.gameEnded();
		gamePane.setStatusText("Untentschieden");
		gamePane.enableButtons(false);
		gamePane.receivedMessage(null, "Es ist kein Zug mehr möglich. Das Spiel ist Untentschieden.");
		
	}
}